home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / demo2.zoo / demo / ex / ex_unix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-07-09  |  6.4 KB  |  367 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char *sccsid = "@(#)ex_unix.c    7.7 (Berkeley) 3/9/87; 1.6 (Bellcore)    87/07/09";
  9. #endif not lint
  10.  
  11. #include "ex.h"
  12. #include "ex_temp.h"
  13. #include "ex_tty.h"
  14. #include "ex_vis.h"
  15.  
  16. /*
  17.  * Unix escapes, filtering
  18.  */
  19.  
  20. /*
  21.  * First part of a shell escape,
  22.  * parse the line, expanding # and % and ! and printing if implied.
  23.  */
  24. unix0(warn)
  25.     bool warn;
  26. {
  27.     register char *up, *fp;
  28.     register short c;
  29.     char printub, puxb[UXBSIZE + sizeof (int)];
  30.  
  31.     printub = 0;
  32.     CP(puxb, uxb);
  33.     c = ex_getchar();
  34.     if (c == '\n' || c == EOF)
  35.         error("Incomplete shell escape command@- use 'shell' to get a shell");
  36.     up = uxb;
  37.     do {
  38.         switch (c) {
  39.  
  40.         case '\\':
  41.             if (any(peekchar(), "%#!"))
  42.                 c = ex_getchar();
  43.         default:
  44.             if (up >= &uxb[UXBSIZE]) {
  45. tunix:
  46.                 uxb[0] = 0;
  47.                 error("Command too long");
  48.             }
  49.             *up++ = c;
  50.             break;
  51.  
  52.         case '!':
  53.             fp = puxb;
  54.             if (*fp == 0) {
  55.                 uxb[0] = 0;
  56.                 error("No previous command@to substitute for !");
  57.             }
  58.             printub++;
  59.             while (*fp) {
  60.                 if (up >= &uxb[UXBSIZE])
  61.                     goto tunix;
  62.                 *up++ = *fp++;
  63.             }
  64.             break;
  65.  
  66.         case '#':
  67.             fp = altfile;
  68.             if (*fp == 0) {
  69.                 uxb[0] = 0;
  70.                 error("No alternate filename@to substitute for #");
  71.             }
  72.             goto uexp;
  73.  
  74.         case '%':
  75.             fp = savedfile;
  76.             if (*fp == 0) {
  77.                 uxb[0] = 0;
  78.                 error("No filename@to substitute for %%");
  79.             }
  80. uexp:
  81.             printub++;
  82.             while (*fp) {
  83.                 if (up >= &uxb[UXBSIZE])
  84.                     goto tunix;
  85.                 *up++ = *fp++ | QUOTE;
  86.             }
  87.             break;
  88.         }
  89.         c = ex_getchar();
  90.     } while (c == '"' || c == '|' || !endcmd(c));
  91.     if (c == EOF)
  92.         ungetchar(c);
  93.     *up = 0;
  94.     if (!inopen)
  95.         resetflav();
  96.     if (warn)
  97.         ckaw();
  98.     if (warn && hush == 0 && chng && xchng != chng && value(WARN) && dol > zero) {
  99.         xchng = chng;
  100.         vnfl();
  101.         ex_printf(mesg("[No write]|[No write since last change]"));
  102.         noonl();
  103.         flush();
  104.     } else
  105.         warn = 0;
  106.     if (printub) {
  107.         if (uxb[0] == 0)
  108.             error("No previous command@to repeat");
  109.         if (inopen) {
  110.             splitw++;
  111.             vclean();
  112.             vgoto(WECHO, 0);
  113.         }
  114.         if (warn)
  115.             vnfl();
  116.         if (hush == 0)
  117.             lprintf("!%s", uxb);
  118.         if (inopen && Outchar != termchar) {
  119.             vclreol();
  120.             vgoto(WECHO, 0);
  121.         } else
  122.             putnl();
  123.         flush();
  124.     }
  125. }
  126.  
  127. /*
  128.  * Do the real work for execution of a shell escape.
  129.  * Mode is like the number passed to open system calls
  130.  * and indicates filtering.  If input is implied, newstdin
  131.  * must have been setup already.
  132.  */
  133. ttymode
  134. unixex(opt, up, newstdin, mode)
  135.     char *opt, *up;
  136.     int newstdin, mode;
  137. {
  138.     int pvec[2];
  139.     ttymode f;
  140.     register char *p;
  141.     char suxb[UXBSIZE + sizeof(int)];
  142.  
  143.     signal(SIGINT, SIG_IGN);
  144. #ifdef SIGTSTP
  145.     if (dosusp)
  146.         signal(SIGTSTP, SIG_DFL);
  147. #endif
  148.     if (inopen)
  149.         f = setty(normf);
  150.     if ((mode & 1) && pipe(pvec) < 0) {
  151.         /* Newstdin should be io so it will be closed */
  152.         if (inopen)
  153.             ignore(setty(f));
  154.         error("Can't make pipe for filter");
  155.     }
  156.     /*
  157.      * Some SHELLs don't strip the  8th bit, so do it here.
  158.      */
  159.     if (up) {
  160.         for (p = suxb; *up && p < &suxb[UXBSIZE]; p++, up++)
  161.             *p = *up & TRIM;
  162.         *p = 0;
  163.         up = suxb;
  164.     }
  165. #ifndef VFORK
  166.     pid = fork();
  167. #else
  168.     pid = vfork();
  169. #endif
  170.     if (pid < 0) {
  171.         if (mode & 1) {
  172.             close(pvec[0]);
  173.             close(pvec[1]);
  174.         }
  175.         setrupt();
  176.         error("No more processes");
  177.     }
  178.     if (pid == 0) {
  179.         if (mode & 2) {
  180.             close(0);
  181.             dup(newstdin);
  182.             close(newstdin);
  183.         }
  184.         if (mode & 1) {
  185.             close(pvec[0]);
  186.             close(1);
  187.             dup(pvec[1]);
  188.             if (inopen) {
  189.                 close(2);
  190.                 dup(1);
  191.             }
  192.             close(pvec[1]);
  193.         }
  194.         if (io)
  195.             close(io);
  196.         if (tfile)
  197.             close(tfile);
  198. #ifdef EXSTRINGS
  199.         close(erfile);
  200. #endif
  201.         signal(SIGHUP, oldhup);
  202.         signal(SIGQUIT, oldquit);
  203.         if (ruptible)
  204.             signal(SIGINT, SIG_DFL);
  205.         execl(svalue(SHELL), "sh", opt, up, (char *) 0);
  206.         ex_printf("No %s!\n", svalue(SHELL));
  207.         error(NOSTR);
  208.     }
  209.     if (mode & 1) {
  210.         io = pvec[0];
  211.         close(pvec[1]);
  212.     }
  213.     if (newstdin)
  214.         close(newstdin);
  215.     return (f);
  216. }
  217.  
  218. /*
  219.  * Wait for the command to complete.
  220.  * F is for restoration of tty mode if from open/visual.
  221.  * C flags suppression of printing.
  222.  */
  223. unixwt(c, f)
  224.     bool c;
  225.     ttymode f;
  226. {
  227.  
  228.     waitfor();
  229. #ifdef SIGTSTP
  230.     if (dosusp)
  231.         signal(SIGTSTP, onsusp);
  232. #endif
  233.     if (inopen)
  234.         ignore(setty(f));
  235.     setrupt();
  236.     if (!inopen && c && hush == 0) {
  237.         ex_printf("!\n");
  238.         flush();
  239.         termreset();
  240.         gettmode();
  241.     }
  242. }
  243.  
  244. /*
  245.  * Setup a pipeline for the filtration implied by mode
  246.  * which is like a open number.  If input is required to
  247.  * the filter, then a child editor is created to write it.
  248.  * If output is catch it from io which is created by unixex.
  249.  */
  250. filter(mode)
  251.     register int mode;
  252. {
  253.     static int pvec[2];
  254.     ttymode f;    /* mjm: was register */
  255.     register int lines = lineDOL();
  256.     struct stat statb;
  257.  
  258.     mode++;
  259.     if (mode & 2) {
  260.         signal(SIGINT, SIG_IGN);
  261.         if (pipe(pvec) < 0)
  262.             error("Can't make pipe");
  263.         pid = fork();
  264.         io = pvec[0];
  265.         if (pid < 0) {
  266.             setrupt();
  267.             close(pvec[1]);
  268.             error("No more processes");
  269.         }
  270.         if (pid == 0) {
  271.             setrupt();
  272.             io = pvec[1];
  273.             close(pvec[0]);
  274.             putfile(1);
  275.             ex_exit(0);
  276.         }
  277.         close(pvec[1]);
  278.         io = pvec[0];
  279.         setrupt();
  280.     }
  281.     f = unixex("-c", uxb, (mode & 2) ? pvec[0] : 0, mode);
  282.     if (mode == 3) {
  283.         ex_delete(0);
  284.         addr2 = addr1 - 1;
  285.     }
  286.     if (mode & 1) {
  287.         if(FIXUNDO)
  288.             undap1 = undap2 = addr2+1;
  289.         if (fstat(io, &statb) < 0)
  290.             bsize = LBSIZE;
  291.         else {
  292.             bsize = statb.st_blksize;
  293.             if (bsize <= 0)
  294.                 bsize = LBSIZE;
  295.         }
  296.         ignore(append(getfile, addr2));
  297. #ifdef TRACE
  298.         if (trace)
  299.             vudump("after append in filter");
  300. #endif
  301.     }
  302.     close(io);
  303.     io = -1;
  304.     unixwt(!inopen, f);
  305.     netchHAD(lines);
  306. }
  307.  
  308. /*
  309.  * Set up to do a recover, getting io to be a pipe from
  310.  * the recover process.
  311.  */
  312. recover()
  313. {
  314.     static int pvec[2];
  315.  
  316.     if (pipe(pvec) < 0)
  317.         error(" Can't make pipe for recovery");
  318.     pid = fork();
  319.     io = pvec[0];
  320.     if (pid < 0) {
  321.         close(pvec[1]);
  322.         error(" Can't fork to execute recovery");
  323.     }
  324.     if (pid == 0) {
  325.         close(2);
  326.         dup(1);
  327.         close(1);
  328.         dup(pvec[1]);
  329.             close(pvec[1]);
  330.         execl(EXRECOVER, "exrecover", svalue(DIRECTORY), file, (char *) 0);
  331.         close(1);
  332.         dup(2);
  333.         error(" No recovery routine");
  334.     }
  335.     close(pvec[1]);
  336. }
  337.  
  338. /*
  339.  * Wait for the process (pid an external) to complete.
  340.  */
  341. waitfor()
  342. {
  343.     int stat = 0;
  344.  
  345.     do {
  346.         rpid = wait(&stat);
  347.         if (rpid == pid)
  348.             status = stat;
  349.     } while (rpid != -1);
  350.     status = (status >> 8) & 0377;
  351. }
  352.  
  353. /*
  354.  * The end of a recover operation.  If the process
  355.  * exits non-zero, force not edited; otherwise force
  356.  * a write.
  357.  */
  358. revocer()
  359. {
  360.  
  361.     waitfor();
  362.     if (pid == rpid && status != 0)
  363.         edited = 0;
  364.     else
  365.         change();
  366. }
  367.